import sys

def print_help():
    print("""
bratz — сценарий для сравнения двух выравниваний одних и тех же последовательностей.

Запуск:
    python bratz.py file1.sto file2.sto [-i] [-o output.txt] [-h]

Обязательные параметры:
    file1, file2 — два выравнивания в формате .sto/.stk

Опции:
    -h — показать справку
    -i — учитывать блоки длиной 1 колонку
    -o name — сохранить совпадающие колонки в файл name

Вывод:
    Статистика и блоки совпадающих колонок: (i-j, s-m, l)
""")

def read_alignment(filepath):
    sequences = []
    with open(filepath, 'r') as file:
        for line in file:
            if not line.strip() or line[0] in "#/":
                continue  # Пропускаем комментарии и пустые строки
            name, seq = line.strip().split()  # Считываем имя и последовательность
            sequences.append((name, seq))
    sequences.sort()  # Сортируем по имени
    return sequences

def build_column_vectors(sequences):
    num_seqs = len(sequences)
    aln_len = len(sequences[0][1])  # Длина выравнивания
    vectors = [[] for _ in range(aln_len)]  # Создаём пустые списки для каждого столбца

    for i in range(num_seqs):
        seq = sequences[i][1]
        pos_counter = 1
        for j, char in enumerate(seq):
            if char == '-':
                vectors[j].append('-')  # Для дефиса
            else:
                vectors[j].append(str(pos_counter))  # Для символа сохраняем номер позиции
                pos_counter += 1
    return [tuple(col) for col in vectors]  # Возвращаем колонки как неизменяемые кортежи

def find_matching_columns(vec1, vec2):
    matches = []
    for i, col1 in enumerate(vec1):
        if col1 in vec2:  # Если колонка из первого выравнивания есть во втором
            j = vec2.index(col1)  # Находим индекс этой колонки во втором выравнивании
            matches.append((i + 1, j + 1))  # Индексы совпавших столбцов (с 1)
    return matches

def find_blocks(matches, include_single=False):
    blocks = []
    if not matches:
        return blocks

    a, b = matches[0]
    for i in range(1, len(matches)):
        prev_i, prev_j = matches[i - 1]
        curr_i, curr_j = matches[i]
        if curr_i == prev_i + 1 and curr_j == prev_j + 1:
            if i == len(matches) - 1:  # Если последняя колонка
                blocks.append((f"{a}-{curr_i}", f"{b}-{curr_j}", curr_i - a + 1))
        else:
            if include_single or prev_i > a:  # Если блок состоит из одной колонки или длиннее
                blocks.append((f"{a}-{prev_i}", f"{b}-{prev_j}", prev_i - a + 1))
            a, b = curr_i, curr_j  # Обновляем начало нового блока
    return blocks

def main():
    args = sys.argv
    if '-h' in args or len(args) < 3:
        print_help()
        return

    file1 = args[1]
    file2 = args[2]
    include_single = '-i' in args  # Флаг для учёта блоков длиной 1 колонка
    output_file = args[args.index('-o') + 1] if '-o' in args else None  # Файл для записи совпадений

    aln1 = read_alignment(file1)
    aln2 = read_alignment(file2)

    if len(aln1) != len(aln2):
        print("Ошибка: количество последовательностей не совпадает.")  # Проверка на совпадение числа последовательностей
        return

    vec1 = build_column_vectors(aln1)
    vec2 = build_column_vectors(aln2)

    matches = find_matching_columns(vec1, vec2)  # Находим совпавшие колонки
    blocks = find_blocks(matches, include_single=include_single)  # Группируем совпадения в блоки

    # Выводим статистику
    len1 = len(vec1)
    len2 = len(vec2)
    print(f"Число последовательностей: {len(aln1)}")
    print(f"Длина первого выравнивания: {len1}")
    print(f"Длина второго выравнивания: {len2}")
    print(f"Процент совпадающих колонок в первом выравнении: {round(len(matches) / len1 * 100, 2)} %")
    print(f"Процент совпадающих колонок во втором выравнении: {round(len(matches) / len2 * 100, 2)} %")
    print(f"Число совпадающих блоков: {len(blocks)}")
    for block in blocks:
        print(block)

    if output_file:
        with open(output_file, 'w') as f:
            for pair in matches:
                f.write(f"{pair}\n")  # Записываем совпавшие колонки в файл

if __name__ == "__main__":
    main()
